home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 6 / Amiga Format AFCD06 (Nov 1996, Issue 90).iso / serious / shareware / text / wordwrap / wordwrap.c < prev    next >
C/C++ Source or Header  |  1996-08-18  |  5KB  |  159 lines

  1. ; /*
  2. gcc -noixemul wordwrap.c -o wordwrap
  3. quit 0 ; */
  4. /*************************************************************************\
  5.   wordwrap.c:
  6.     Reformat a text on the input stream to a given maximum line length.
  7.   arguments and their meanings:
  8.     -l<len>         line length, defaults to 75
  9.     -b              protect blank lines
  10.     -i              protect indentation
  11.     -i<indent>       " , enforcing a fixed indentation width
  12.     -s<len>         protect short lines
  13.     -m<width>       add a left margin
  14.     -M<width>       ignore a left margin on the input
  15. \*************************************************************************/
  16.  
  17. #include <stdio.h>
  18. #include <string.h>
  19.  
  20. char version[] = "$VER: wordwrap 1.1 (18.08.96)";
  21.  
  22. #define MAXLEN 200  /* max. size of an input word */
  23. int shortchars = 0;
  24.  
  25. int getword(char s[], int lim);
  26. void help(char *s);
  27.  
  28. int main(int argc, char* argv[])
  29. {
  30.   int i, lword, lline, dented;
  31.   char *s, c, word[MAXLEN], newline[MAXLEN];
  32.   /* adjustable parameters: */
  33.   int lmax = 75, blanks = 0, indent = 0;
  34.   unsigned int imargin = 0, omargin = 0;
  35.  
  36.   while (--argc) {
  37.     s = *++argv;
  38.     if (*s++ == '-') {
  39.       switch (*s++) {
  40.         case 'l': lmax = atoi(s); break;
  41.         case 'b': blanks = 1; break;
  42.         case 's': shortchars = atoi(s); break;
  43.         case 'm': omargin = atoi(s); break;
  44.         case 'M': imargin = atoi(s); break;
  45.         case 'i': indent = -1;
  46.           if (isdigit(*s)) indent = atoi(s);
  47.           break;
  48.         default: help(argv[0]); return 10;
  49.       }
  50.     } else {
  51.       help(argv[0]); return 10;
  52.     }
  53.   }
  54.   /* prepare the left margin string: */
  55.   if (omargin>MAXLEN-2) omargin = MAXLEN-2;
  56.   newline[0] = '\n';
  57.   for (i=1; i<=omargin; i++) newline[i] = ' ';
  58.   newline[omargin+1] = '\0';
  59.   /* let's go */
  60.   lline = 0; dented = 0;
  61.   while (lword = getword(word, MAXLEN)) {
  62.     if (word[0] == '\n') {   /* has read a blank line */
  63.       if (blanks) {
  64.         if (lline) printf("%s", newline);
  65.         printf("%s", newline); lline = 0;
  66.       }
  67.     } else if (isspace(word[0])) {   /* indented line */
  68.       if (indent && lword>imargin) {
  69.         if (lline) printf("%s", newline);
  70.         if (indent>0) {
  71.           for (lline = 0; lline<indent; lline++) putchar(' ');
  72.         } else {
  73.           printf("%s", &word[imargin]); lline = lword-imargin;
  74.         }
  75.         dented = 1;
  76.       }
  77.     } else {    /* regular word */
  78.       if ((c = word[lword-1]) == '\n')  /* "short line" break request? */
  79.         word[--lword] = '\0';
  80.       if (lline == 0 || dented) {   /* at the start of the line */
  81.         printf("%s", word); lline += lword; dented = 0;
  82.       } else {     /* append to an existing line */
  83.         if (lline + lword < lmax) {
  84.           printf(" %s", word); lline += lword + 1;
  85.         } else {
  86.           printf("%s%s", newline, word); lline = lword;
  87.         }
  88.       }
  89.       if (c == '\n') {   /* "short line" break pending */
  90.         printf("%s", newline); lline = 0;
  91.       }
  92.     }
  93.   }
  94.   if (lline)
  95.     putchar('\n');
  96.   return 0;
  97. }
  98.  
  99.  
  100. void help(char *s)
  101. /* print a help text and nag about illegal parameter <s> */
  102. {
  103.   if (s) fprintf(stderr,"illegal option '%s'\n", s);
  104.   fprintf(stderr,"'wordwrap' command line parameters:\n", s);
  105.   fprintf(stderr," -l<len>                line length, defaults to 75\n");
  106.   fprintf(stderr," -b                     protect blank lines\n");
  107.   fprintf(stderr," -i / -i<width>         protect indentation\n");
  108.   fprintf(stderr," -s<len>                protect lines shorter than <len>\n");
  109.   fprintf(stderr," -m<width> / -M<width>  add/strip left margin\n");
  110. }
  111.  
  112.  
  113. int getword(char s[], int lim)
  114. /* Copies one word of the input stream to s[] (return value is strlen(s)),
  115.  * then skips all subsequent spaces, stopping at the next word or EOL.
  116.  * - will return "\n" for an empty line
  117.  * - will return a string of blanks for a line starting with blanks
  118.  * - will append "\n" to the last word on a "short" line
  119.  * - will return an empty string at EOF
  120.  */
  121. {
  122.   int c, i = 0;
  123.   static int nonblanks = 0;
  124.  
  125.   c = getchar();
  126.   if (c == EOF) {
  127.     s[0] = '\0'; return 0;
  128.   }
  129.   if (isspace(c)) {  /* indented line (or even a blank line?) */
  130.     while (isspace(c) && c != '\n') {
  131.       if (i<lim-1) s[i++] = c;
  132.       c = getchar();
  133.     }
  134.     if (c == '\n' || c == EOF) {
  135.       i = 0; s[i++] = '\n';   /* yeah, a blank line */
  136.     }
  137.   } else {       /* read a word of non-blanks */
  138.     while (isgraph(c)) {
  139.       if (i<lim-1)
  140.         s[i++] = c;
  141.       else {
  142.         fprintf(stderr, "warning: long input word (> %d chars)\n", lim);
  143.         break;
  144.       }
  145.       c = getchar();
  146.     }
  147.     nonblanks += i;
  148.     while (isspace(c) && c != '\n')    /* skip blanks */
  149.       c = getchar();
  150.     if (c == '\n') {         /* was this a "short line"? */
  151.       if (nonblanks <= shortchars) s[i++] = '\n';
  152.       nonblanks = 0;
  153.     }
  154.   }
  155.   if (isgraph(c))   /* did we stop on a non-blank character? */
  156.     ungetc(c, stdin);
  157.   s[i] = '\0'; return i;
  158. }
  159.